package info.niwota.search;

import java.io.OutputStream;
import java.io.Writer;
import java.net.URL;
import java.security.Key;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.google.appengine.api.urlfetch.HTTPHeader;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;

public class HttpClient {

	private static String parseType(String s) {
		int idx = s.indexOf(";");
		return idx == -1 ? s : s.substring(0, idx);
	}
	
	private static String parseCharset(String s) {
		//text/html; charset=UTF-8
		int idx = s.toLowerCase().indexOf("charset=");
		return idx == -1 ? null : s.substring(idx + 8);
	}
	
	public static void fetch(String query, String[] terms, int scramble, HttpServletRequest req, HttpServletResponse resp) throws Exception {
		URLFetchService fs = URLFetchServiceFactory.getURLFetchService();
		HTTPResponse fresp = fs.fetch(new URL(query));
		byte[] content = fresp.getContent();
		//URL finalUrl = fresp.getFinalUrl();
		//int rc = fresp.getResponseCode();
		List<HTTPHeader> headers = fresp.getHeaders();

		//Content-Type:text/html; charset=UTF-8
		String type = "text/html";
		String charset = "UTF-8";
		for(HTTPHeader header : headers) {
			String name = header.getName();
			String value = header.getValue();
			if (name.equalsIgnoreCase("Content-Type")) {
				type = parseType(value);
				charset = parseCharset(value);
				break;
			}
		}
		type = (type == null ? "text/html" : type);
		charset = (charset == null ? "UTF-8" : charset);
		
		resp.setContentType(type);
		
		if (type.equalsIgnoreCase("text/html")) {
			final HttpSession sess = req.getSession();
			HtmlScrambler scrambler = (HtmlScrambler) sess.getAttribute(Constants.HTML_SCRAMBLER);
			if (scrambler == null) {
				scrambler = new HtmlScrambler();
				sess.setAttribute(Constants.HTML_SCRAMBLER, scrambler);
			}
			Key key = (Key) sess.getAttribute(Constants.HTML_KEY);
			if (key == null) {
				key = CryptUtils.generateKey();
				sess.setAttribute(Constants.HTML_KEY, key);
			}
			
			String s = scrambler.rewrite(query, new String(content, charset), key, terms, scramble);
			
			//
			final Writer out = resp.getWriter();
			out.write(s);
			//
			String js = "<script type=\"text/javascript\" src=\"/script.js\"></script>";
			out.write(js);
			
			out.flush();
		} else if (type.startsWith("text/")) {
			final Writer out = resp.getWriter();
			out.write(new String(content, charset));
			out.flush();
		} else if (type.startsWith("audio/") || type.startsWith("image/") || type.startsWith("video/")) {
			final OutputStream out = resp.getOutputStream();
			out.write(content);
			out.flush();
		}
	}
}
